// ignore_for_file: non_constant_identifier_names

import 'dart:io';

import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:dart_bean/field_info.dart';
import 'package:dart_bean/generator.dart';
import 'package:dart_bean/setting.dart';
import 'package:dart_bean/util/ext.dart';
import 'package:dart_bean/util/visitor.dart';

class CassInfo {
  final File file;
  final ClassDeclaration self;
  final String content;
  late final String name = self.name.toString();
  final List<SimpleImportDirective> imports;
  final List<PartDirective> parts;
  late List<FieldInfo> fields;

  CassInfo(this.file, this.imports, this.parts, this.self, this.content) {
    _initFields();
  }

  ///通过 class 关键字，分割类。Dart不支持像Java的内部类。
  static List<CassInfo> parseFileToClasses(Directory libDir, File file) {
    String fileContent = file.readAsStringSync();

    final List<CassInfo> classInfoList = [];
    final v = ClassVisitor(file);
    parseString(content: fileContent).unit.visitChildren(v);
    final imports = v.imports.map((e) => SimpleImportDirective(e.uri.stringValue!, e)).toList();
    final classDeclarations = v.classDeclarations;
    final officialBean = _hasOfficialPartImport(file, v.parts);
    if (ignoreOfficialBean && officialBean && v.classDeclarations.isNotEmpty) {
      print("ignore OfficialBean: ${printFilePath(file)}");
      return classInfoList;
    }

    for (var c in classDeclarations) {
      final classContent = fileContent.substring(c.offset, c.end);
      final ci = CassInfo(file, imports, v.parts, c, classContent);
      classInfoList.add(ci);
    }
    return classInfoList;
  }

  void _initFields() {
    final fv = FieldVisitor(this);
    parseString(content: content).unit.visitChildren(fv);
    fields = fv.fields;
  }

  static bool _hasOfficialPartImport(File file, List<PartDirective> parts) {
    final target = getPartFile(Generator.libDir, Generator.genDir, file).path.substringAfterLast(separator);
    return parts.any((e) => e.uri.stringValue == target);
  }
}

class SimpleImportDirective {
  final ImportDirective? self;
  final String uri;

  SimpleImportDirective(this.uri, [this.self]);
}
